﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.IO;
using System.Data;
using Microsoft.Office.Interop.Excel;
using System.Windows;
using PanGu;

namespace PatientInformationExtract.MainInterface.Models.XMLCS
{
    class OrdersInfo : IExcelInfo
    {
        public string FileName
        {
            get
            {
                return "d_orders.XLS";
            }
        }
        private int _rowsint;
        public int RowsCount { get { return this._rowsint; } }
        private int _columnsint;
        public int ColumnsCount { get { return this._columnsint; } }
        private string _filePath;
        public string FilePath { get { return this._filePath; } }
        private string _patientID;
        public string PatientID { get { return this._patientID; } }
        private string _visitID;
        public string VisitID { get { return this._visitID; } }
        private List<XmlElement> _xmlElement;
        public List<XmlElement> XmlElements { get { return this._xmlElement; } }
        private XmlDocument _xml;
        public XmlDocument XmlDoc { get { return this._xml; } }
        private bool _isInitialized;
        public bool IsInitialized { get { return this._isInitialized; } }

        public OrdersInfo(XmlDocument xml)
        {
            this._xml = xml;
            this._patientID = null;
            this._visitID = null;
            this._filePath = null;
            _xmlElement = new List<XmlElement>();
            _rowsint = 0;
            _columnsint = 0;
            _isInitialized = false;
        }

        public void Initialize(string filePath, Workbooks excelWBs)
        {
            if (!_isInitialized)
            {
                _isInitialized = true;
                FileInfo file = new FileInfo(filePath);
                if (file.Name == this.FileName)
                {
                    ExcelOperate eO = new ExcelOperate(filePath, 1, ref excelWBs);
                    try
                    {
                        this._columnsint = eO.ColumnsCount;
                        this._rowsint = eO.RowsCount;
                        Validate(eO);
                        this._patientID = eO.GetColumnStringByIndex(1);
                        string[] stratTime = eO.GetColumnByIndex(13);
                        string[] endTime = eO.GetColumnByIndex(14);
                        string[] type = eO.GetColumnByIndex(6);
                        string[] name = eO.GetColumnByIndex(7);
                        string[] amount = eO.GetColumnByIndex(8);
                        string[] unit = eO.GetColumnByIndex(9);
                        string[] frequency = eO.GetColumnByIndex(15);
                        string[] duration = eO.GetColumnByIndex(19);
                        string[] orderBy = eO.GetColumnByIndex(21);
                        string[] performBy = eO.GetColumnByIndex(23);
                        string[] method = eO.GetColumnByIndex(10);
                        for (int i = 1; i <= _rowsint; i++)
                        {
                            _xmlElement.Add(NewMedicalInterventionElement(stratTime[i - 1], endTime[i - 1], name[i - 1], type[i - 1], amount[i - 1], unit[i - 1], method[i - 1], orderBy[i - 1], performBy[i - 1], frequency[i - 1], duration[i - 1], FileName));
                        }
                        eO.Release();
                    }
                    catch (Exception ex)
                    {
                        eO.Release();
                        throw new Exception(String.Format(PatientInfoErrorMessages.InitializationFailed, FileName, ex.Message), ex);
                    }
                    _isInitialized = true;
                }
                else
                {
                    throw new Exception(String.Format(PatientInfoErrorMessages.FileNotMatch, FileName));
                }
            }
            else
            {
                throw new Exception(String.Format(PatientInfoErrorMessages.AlreadyInitialized, FileName));
            }
        }

        private void Validate(ExcelOperate excelOperate)
        {
            if (excelOperate.GetCellStringByIndex(1, 2) != ""
                || excelOperate.GetCellStringByIndex(1, 3) != ""
                || excelOperate.GetCellStringByIndex(1, 4) != ""
                || excelOperate.GetCellStringByIndex(1, 5) != ""
                || excelOperate.GetCellStringByIndex(1, 11) != ""
                || excelOperate.GetCellStringByIndex(1, 16) != ""
                || excelOperate.GetCellStringByIndex(1, 17) != ""
                )
            {
                throw new Exception(String.Format(PatientInfoErrorMessages.ExcelFormatValidationFailed, FileName));
            }
        }

        private XmlElement NewMedicalInterventionElement(string startTime, string endTime, string name, string type, string amount, string unit, string method, string orderBy, string performBy, string frequency, string duration, string originalSource)
        {
            XmlElement medicalInterventionE = _xml.CreateElement("MedicalIntervention");
            XmlElement nameE = _xml.CreateElement("Name");
            XmlElement amountE = _xml.CreateElement("Amount");
            XmlElement frequencyE = _xml.CreateElement("Frequency");
            XmlElement otherE = _xml.CreateElement("Other");
            XmlElement startTimeE = _xml.CreateElement("StartTime");
            XmlElement endTimeE = _xml.CreateElement("EndTime");
            XmlElement orderByE = _xml.CreateElement("OrderBy");
            XmlElement performByE = _xml.CreateElement("PerformBy");
            XmlElement originalSourceE = _xml.CreateElement("OriginalSource");

            DateTime time;
            if (startTime != "")
            {
                time = Convert.ToDateTime(startTime);
                startTime = time.ToString("yyyy-MM-ddTHH:mm:ssZ");
            }
            if (endTime != "")
            {
                time = Convert.ToDateTime(endTime);
                endTime = time.ToString("yyyy-MM-ddTHH:mm:ssZ");
            }
            medicalInterventionE.SetAttribute("OccurTime", startTime);
            medicalInterventionE.SetAttribute("Type", type);
            nameE.InnerText = name;
            medicalInterventionE.AppendChild(nameE);
            if (amount != "")
            {
                amountE.InnerText = amount;
                if (unit != "")
                {
                    amountE.SetAttribute("Unit", unit);
                }
                medicalInterventionE.AppendChild(amountE);
            }
            if (frequency != "")
            {
                frequencyE.InnerText = frequency;
                if (duration != "")
                {
                    frequencyE.SetAttribute("Duration", duration);
                }
                medicalInterventionE.AppendChild(frequencyE);
            }
            startTimeE.InnerText = startTime;
            medicalInterventionE.AppendChild(startTimeE);
            endTimeE.InnerText = endTime;
            medicalInterventionE.AppendChild(endTimeE);
            orderByE.InnerText = orderBy;
            medicalInterventionE.AppendChild(orderByE);
            performByE.InnerText = performBy;
            medicalInterventionE.AppendChild(performByE);
            if (method != "")
            {
                otherE.SetAttribute("Annotation", "Method");
                otherE.InnerText = method;
                medicalInterventionE.AppendChild(otherE);
            }
            originalSourceE.InnerText = originalSource;
            medicalInterventionE.AppendChild(originalSourceE);
            return medicalInterventionE;
        }

        public System.Data.DataTable GetDataTable()
        {
            System.Data.DataTable dt = null;
            if (_filePath != null)
            {
                FullExcelOperate eO = new FullExcelOperate(_filePath, 1);
                dt = eO.ToDataTable();
                eO.Release();
                eO = null;
            }
            return dt;
        }

        public void SetXML(ref XmlDocument xml)
        {
            this._xml = xml;
        }
    }
}
